{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ecd1d2ee",
   "metadata": {},
   "source": [
    "\n",
    "# Cloud Memory Operations with Mem0 MemoryClient\n",
    "\n",
    "This example demonstrates how to use Mem0's cloud-based MemoryClient for managing conversational memory and user preferences with both synchronous and asynchronous operations.\n",
    "\n",
    "## Overview\n",
    "\n",
    "This example showcases cloud-based memory management operations where we:\n",
    "\n",
    "1. **Initialize MemoryClient instances** for both sync and async cloud operations\n",
    "2. **Store conversation history** in the cloud with rich metadata\n",
    "3. **Perform concurrent operations** using async/await patterns\n",
    "4. **Search and filter memories** using natural language and structured queries\n",
    "\n",
    "By using the cloud-based MemoryClient with async operations, you can leverage Mem0's managed infrastructure while performing multiple memory operations simultaneously. This is ideal for production applications that need scalable memory management without managing local storage.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a63847c4",
   "metadata": {},
   "source": [
    "## Setup and Imports\n",
    "\n",
    "First, we'll import the necessary libraries for working with Mem0's cloud-based memory management system. We'll use both synchronous and asynchronous clients to demonstrate different usage patterns.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f98af04f",
   "metadata": {},
   "source": [
    "# Install the required dependencies:\n",
    "%pip install agentops\n",
    "%pip install mem0ai\n",
    "%pip install python-dotenv"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "69b834f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Install the required dependencies:\n",
    "%pip install agentops\n",
    "%pip install mem0ai\n",
    "%pip install python-dotenv"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e552e158",
   "metadata": {},
   "outputs": [],
   "source": [
    "from mem0 import MemoryClient, AsyncMemoryClient\n",
    "import agentops\n",
    "import os\n",
    "import asyncio\n",
    "from dotenv import load_dotenv"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a70fadde",
   "metadata": {},
   "source": [
    "## Environment Configuration\n",
    "\n",
    "Load environment variables including API keys for AgentOps, Mem0, and OpenAI. These credentials are required for authenticating with the respective services.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "969f7c42",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load environment variables\n",
    "load_dotenv()\n",
    "os.environ[\"AGENTOPS_API_KEY\"] = os.getenv(\"AGENTOPS_API_KEY\")\n",
    "mem0_api_key = os.getenv(\"MEM0_API_KEY\")\n",
    "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f630d40",
   "metadata": {},
   "source": [
    "## Sample Data Setup\n",
    "\n",
    "Define user identifiers and sample data that will be used throughout the demonstration. This includes user IDs for tracking memory ownership and agent/session identifiers for context.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0abf3fe7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Sample user data for demonstration\n",
    "user_id = \"alice_demo\"\n",
    "agent_id = \"assistant_demo\"\n",
    "run_id = \"session_001\"\n",
    "\n",
    "# Sample conversation data demonstrating preference discovery through dialogue\n",
    "sample_messages = [\n",
    "    {\"role\": \"user\", \"content\": \"I'm planning to watch a movie tonight. Any recommendations?\"},\n",
    "    {\"role\": \"assistant\", \"content\": \"How about a thriller? They can be quite engaging.\"},\n",
    "    {\"role\": \"user\", \"content\": \"I'm not a big fan of thriller movies but I love sci-fi movies.\"},\n",
    "    {\n",
    "        \"role\": \"assistant\",\n",
    "        \"content\": \"Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future.\",\n",
    "    },\n",
    "]\n",
    "\n",
    "# Sample user preferences representing various personal attributes\n",
    "sample_preferences = [\n",
    "    \"I prefer dark roast coffee over light roast\",\n",
    "    \"I exercise every morning at 6 AM\",\n",
    "    \"I'm vegetarian and avoid all meat products\",\n",
    "    \"I love reading science fiction novels\",\n",
    "    \"I work in software engineering\",\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "046d2588",
   "metadata": {},
   "source": [
    "## Synchronous Memory Operations\n",
    "\n",
    "The following function demonstrates how to use the synchronous MemoryClient for sequential cloud memory operations. This approach is straightforward but operations execute one after another.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "63d2f851",
   "metadata": {},
   "outputs": [],
   "source": [
    "def demonstrate_sync_memory_client(sample_messages, sample_preferences, user_id):\n",
    "    \"\"\"\n",
    "    Demonstrate synchronous MemoryClient operations with cloud storage.\n",
    "\n",
    "    This function performs sequential cloud memory operations including:\n",
    "    - Initializing cloud-based memory client with API authentication\n",
    "    - Adding conversation messages to cloud storage\n",
    "    - Storing user preferences with metadata\n",
    "    - Searching memories using natural language\n",
    "    - Retrieving memories with filters\n",
    "    - Cleaning up cloud memories\n",
    "\n",
    "    \"\"\"\n",
    "    agentops.start_trace(\"mem0_memoryclient_sync_example\", tags=[\"mem0_memoryclient_example\"])\n",
    "    try:\n",
    "        # Initialize sync MemoryClient with API key for cloud access\n",
    "        client = MemoryClient(api_key=mem0_api_key)\n",
    "\n",
    "        # Add conversation to cloud storage with metadata\n",
    "        result = client.add(\n",
    "            sample_messages,\n",
    "            user_id=user_id,\n",
    "            metadata={\"category\": \"cloud_movie_preferences\", \"session\": \"cloud_demo\"},\n",
    "            version=\"v2\",\n",
    "        )\n",
    "        print(f\"Add result: {result}\")\n",
    "\n",
    "        # Add preferences sequentially to cloud\n",
    "        for i, preference in enumerate(sample_preferences[:3]):  # Limit for demo\n",
    "            # Convert string preference to message format\n",
    "            preference_message = [{\"role\": \"user\", \"content\": preference}]\n",
    "            result = client.add(preference_message, user_id=user_id, metadata={\"type\": \"cloud_preference\", \"index\": i})\n",
    "\n",
    "        # 2. SEARCH operations - leverage cloud search capabilities\n",
    "        search_result = client.search(\"What are the user's movie preferences?\", user_id=user_id)\n",
    "        print(f\"Search result: {search_result}\")\n",
    "\n",
    "        # 3. GET_ALL - retrieve all memories for the user\n",
    "        all_memories = client.get_all(user_id=user_id, limit=10)\n",
    "        print(f\"Cloud memories retrieved: {all_memories}\")\n",
    "\n",
    "        # Cleanup - remove all user memories from cloud\n",
    "        delete_all_result = client.delete_all(user_id=user_id)\n",
    "        print(f\"Delete all result: {delete_all_result}\")\n",
    "        agentops.end_trace(end_state=\"success\")\n",
    "    except Exception:\n",
    "        agentops.end_trace(end_state=\"error\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e629329",
   "metadata": {},
   "source": [
    "## Asynchronous Memory Operations\n",
    "\n",
    "This function showcases the power of asynchronous operations with Mem0's AsyncMemoryClient. By using async/await patterns, we can execute multiple memory operations concurrently, significantly improving performance.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2462a05f",
   "metadata": {},
   "outputs": [],
   "source": [
    "async def demonstrate_async_memory_client(sample_messages, sample_preferences, user_id):\n",
    "    \"\"\"\n",
    "    Demonstrate asynchronous MemoryClient operations with concurrent cloud access.\n",
    "\n",
    "    This function performs concurrent cloud memory operations including:\n",
    "    - Initializing async cloud-based memory client\n",
    "    - Adding multiple memories concurrently using asyncio.gather()\n",
    "    - Performing parallel search operations across cloud storage\n",
    "    - Retrieving filtered memories asynchronously\n",
    "    - Cleaning up cloud memories efficiently\n",
    "\n",
    "    \"\"\"\n",
    "    agentops.start_trace(\"mem0_memoryclient_async_example\", tags=[\"mem0_memoryclient_example\"])\n",
    "    try:\n",
    "        # Initialize async MemoryClient for concurrent cloud operations\n",
    "        async_client = AsyncMemoryClient(api_key=mem0_api_key)\n",
    "\n",
    "        # Add conversation and preferences concurrently to cloud\n",
    "        add_conversation_task = async_client.add(\n",
    "            sample_messages, user_id=user_id, metadata={\"category\": \"async_cloud_movies\", \"session\": \"async_cloud_demo\"}\n",
    "        )\n",
    "\n",
    "        # Create tasks for adding preferences in parallel\n",
    "        add_preference_tasks = [\n",
    "            async_client.add(\n",
    "                [{\"role\": \"user\", \"content\": pref}],\n",
    "                user_id=user_id,\n",
    "                metadata={\"type\": \"async_cloud_preference\", \"index\": i},\n",
    "            )\n",
    "            for i, pref in enumerate(sample_preferences[:3])\n",
    "        ]\n",
    "\n",
    "        # Execute all add operations concurrently\n",
    "        results = await asyncio.gather(add_conversation_task, *add_preference_tasks)\n",
    "        for i, result in enumerate(results):\n",
    "            print(f\"{i + 1}. {result}\")\n",
    "\n",
    "        # 2. Concurrent SEARCH operations - multiple cloud searches in parallel\n",
    "        search_tasks = [\n",
    "            async_client.search(\"movie preferences\", user_id=user_id),\n",
    "            async_client.search(\"food preferences\", user_id=user_id),\n",
    "            async_client.search(\"work information\", user_id=user_id),\n",
    "        ]\n",
    "\n",
    "        # Execute all searches concurrently\n",
    "        search_results = await asyncio.gather(*search_tasks)\n",
    "        for i, result in enumerate(search_results):\n",
    "            print(f\"Search {i + 1} result: {result}\")\n",
    "\n",
    "        # 3. GET_ALL operation - retrieve all memories from cloud\n",
    "        all_memories = await async_client.get_all(user_id=user_id, limit=10)\n",
    "        print(f\"Async cloud memories: {all_memories}\")\n",
    "\n",
    "        # Final cleanup - remove all memories asynchronously\n",
    "        delete_all_result = await async_client.delete_all(user_id=user_id)\n",
    "        print(f\"Delete all result: {delete_all_result}\")\n",
    "\n",
    "        agentops.end_trace(end_state=\"success\")\n",
    "\n",
    "    except Exception:\n",
    "        agentops.end_trace(end_state=\"error\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c5e1af75",
   "metadata": {},
   "source": [
    "## Execute Demonstrations\n",
    "\n",
    "Run both synchronous and asynchronous demonstrations to compare their behavior and performance. The async version typically completes faster due to concurrent operations, especially when dealing with multiple API calls.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a6524b2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Execute both sync and async demonstrations\n",
    "demonstrate_sync_memory_client(sample_messages, sample_preferences, user_id)\n",
    "await demonstrate_async_memory_client(sample_messages, sample_preferences, user_id)"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  },
  "kernelspec": {
   "display_name": "venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
